package com.kingstar.ceres.data.util;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Slf4j
public class FormatUtils {
    private static final Pattern patternBody = Pattern.compile("\\{([^}]*)\\}");
    private static final String ANY_PATTERN=".*";

    public static String parseBody(String body) {
        String text = body;
        Matcher m = patternBody.matcher(text);
        while (m.find()){
            String parse = m.group();
            String parseBody = parse.substring(1).substring(0, parse.length() - 2);

            // 1. 设置显示格式
            String showFormat = parseBody;
            Long change=0L;
            // 日期显示格式 去掉小括号后的内容
            int left = parseBody.indexOf("(");
            if (left >= 0) {
                int right = parseBody.indexOf(")");
                showFormat = showFormat.substring(0, left);
                change=Long.valueOf(parseBody.substring(left+1,right));
            }
            String dateStr = LocalDate.now().plusDays(change).format(DateTimeFormatter.ofPattern(showFormat));
            text = text.replace(parse, dateStr);
        }
        return text;
    }

    public static boolean isPatternFileName(String filename){
        return filename.contains(ANY_PATTERN);
    }

    public static String geneRatePatternFileName(String filename){
        return geneRatePatternFileName(filename,System.currentTimeMillis());
    }

    public static String geneRatePatternFileName(String filename,Long timestamp){
        return filename.replace(ANY_PATTERN,timestamp.toString());
    }

    public static Path checkFilePath(String dir,String fileName){
        log.info("check file path;dir:{},file:{}",dir,fileName);
        //1.非正则文件名
        if (!fileName.contains(ANY_PATTERN)){
            return Paths.get(dir, fileName);
        }
        //2.正则文件名
        Path dirPath = Paths.get(dir);
        if (!Files.exists(dirPath)){
            log.warn("no such file dir:{}",dir);
            return null;
        }
        final Pattern pattern = Pattern.compile(fileName);
        try {
            Path path = Files.list(dirPath).filter(v ->{
                                Matcher matcher = pattern.matcher(v.getFileName().toString());
                                return matcher.matches();
                            }
                    ).sorted(Comparator.comparing(Path::getFileName, Comparator.reverseOrder()))
                    .findFirst().orElse(null);
            return path;
        } catch (IOException e) {
            String format = MessageFormatUtils.format("no such file;dir:{},file:{};", dir, fileName);
            log.error(format,e);
            return null;
        }
    }

    public static List<List<String>> parseCsv(List<String> list,char regex,int quoteCharWrap){
        final CsvParser parser= CsvParser.instance(regex,quoteCharWrap==1);
        List<List<String>> result = list.stream().map(v -> parser.init(v).parse())
                .collect(Collectors.toList());
        list.clear();
        return result;
    }

    private static class CsvParser{
        private final int end=-1;
        private final char quoteChar='"';
        private final char delimiter;
        private final boolean quoteCharWrap;

        private String s;
        private int position=0;
        private int limit;

        private List<String> recordList=new ArrayList<>();
        private StringBuilder sb = new StringBuilder();

        private CsvParser(char delimiter,boolean quoteCharWrap) {
            this.delimiter = delimiter;
            this.quoteCharWrap=quoteCharWrap;
        }

        public static CsvParser instance(){
            return instance(',');
        }

        public static CsvParser instance(char delimiter){
            return new CsvParser(delimiter,Boolean.TRUE);
        }
        public static CsvParser instance(char delimiter,boolean quoteCharWrap){
            return new CsvParser(delimiter,quoteCharWrap);
        }
        public static CsvParser instance(String delimiter){
            return instance(delimiter.charAt(0));
        }

        public List<String> parse(){
            int ch=read();
            while (!endOfString(ch)){
                if (quoteCharWrap && isQuoteChar(ch)){
                    parseEncapsulated();
                }else {
                    parseSimple(ch);
                }
                ch=read();
            }
            return recordList;
        }

        private boolean endOfString(final int ch){
            return ch==end;
        }
        private void parseEncapsulated(){
            int ch=read();
            //while循环中不是-1
            while (!endOfString(ch)){
                if (isQuoteChar(ch)){
                    //是双引号读取下一个字符
                    ch=read();
                    //下一个字符也为双引号时解析一个双引号
                    if(isQuoteChar(ch)){
                        sb.append((char) ch);
                    }else {
                        break;
                    }
                }else {
                    //不是双引号之间加入
                    sb.append((char) ch);
                }
                //读取下一个
                ch=read();
            }
            addRecord();
        }
        private boolean isQuoteChar(final int ch) {
            return ch == quoteChar;
        }
        private boolean isDelimiter(final int ch) {
            return ch == delimiter;
        }
        private void parseSimple(int ch){
            while (!endOfString(ch)){
                if (isDelimiter(ch)){
                    break;
                }
                sb.append((char) ch);
                ch=read();
            }
            addRecord();
        }

        private int read(){
            if (position<limit){
                return s.charAt(position++);
            }
            return end;
        }

        private void addRecord(){
            recordList.add(sb.toString());
            sb=new StringBuilder();
        }

        public CsvParser init(String str){
            this.sb=new StringBuilder();
            s=str;
            this.limit=str.length();
            this.recordList=new ArrayList<>();
            this.position=0;
            return this;
        }
    }
}
